package crafex.engine.entities;

import crafex.engine.graphics.Sprite;
import crafex.engine.tools.FloatVertex2D;
import crafex.engine.tools.IntVertex2D;
import android.graphics.Bitmap;
import android.graphics.Canvas;

public class Entity {
	
	/**the last movement by the enity*/
	protected FloatVertex2D lastMovement = new FloatVertex2D(0, 0);
	/**the current movement of the entity for this loop cycle*/
	protected FloatVertex2D movement;
	/**the movement applied to movement everloop*/;
	protected FloatVertex2D repeatedMovement;
	/**the coordinates of the entity in the world*/
	protected FloatVertex2D coordinates;
	/**the amount of pixels the entity can travel in one cycle*/
	protected float speed;
	/**the health of the entity*/
	protected float health;
	/**the entities sprite*/
	protected Sprite sprite;
	
	public Entity(){
		start();
		coordinates = new FloatVertex2D();
	}
	
	public Entity(Bitmap image){
		start();
		setSprite(new Sprite(image));
	}

	public Entity(Bitmap image, int frames, int cycles){
		
		start();
		coordinates = new FloatVertex2D();
		setSprite(new Sprite(image, frames, cycles, 
				new IntVertex2D( (int) (image.getWidth() * 0.15), (int) (image.getHeight() * 0.15)), 1));
		
	}
	
	public Entity(float x, float y){
		
		start();
		coordinates = new FloatVertex2D(x, y);
		
	}
	
	public Entity(Bitmap image, int frames, int cycles, float x, float y){
		
		start();
		coordinates = new FloatVertex2D(x, y);
		setSprite(new Sprite(image, frames, cycles, new IntVertex2D(image.getWidth(), image.getHeight()), 1));
		
	}
	
	/**init*/
	public void start(){
		movement = new FloatVertex2D();
		lastMovement = new FloatVertex2D();
		repeatedMovement = new FloatVertex2D();
	}
	
	/**resets the entity*/
	public void reset(){
		coordinates = new FloatVertex2D();
		movement = new FloatVertex2D();
		repeatedMovement = new FloatVertex2D();
	}
	
	/**
	 * get the pixel location in the center of the entity
	 * @return center pixel
	 */
	public FloatVertex2D getCenter(){
		FloatVertex2D data = new FloatVertex2D(
				this.getCoordinates().getX() + (int)(this.getSprite().getWidth() * .5), 
				this.getCoordinates().getY() + (int)(this.getSprite().getHeight() * .5));		
		return data;
	}
	
	/**
	 * gets the amount of pixels the entity can move per cycle
	 * @return entity speed
	 */
	public float getSpeed() {
		return speed;
	}
	
	/**
	 * sets the amount of pixels the entity can move per cycle
	 * @param speed
	 */
	public void setSpeed(float speed) {
		this.speed = speed;
	}

	/**
	 * gets the sprite of the entity
	 * @return entity sprite
	 */
	public Sprite getSprite() {
		return sprite;
	}

	/**
	 * sets the entitys sprite
	 * @param sprite
	 */
	private void setSprite(Sprite sprite) {
		this.sprite = sprite;
	}

	protected void setLastMovement(FloatVertex2D lastMovement) {
		this.lastMovement = lastMovement;
	}

	/**
	 * gets the movement for this cycle
	 * @return movement
	 */
	public FloatVertex2D getMovement() {
		return movement;
	}

	/**
	 * sets the amount of movement the entity will do this cycle
	 * @param movement
	 */
	public void setMovement(FloatVertex2D movement) {
		this.movement = movement;
	}
	
	public FloatVertex2D getLastMovement() {
		return lastMovement;
	}

	/**
	 * gets the entitys health
	 * @return health
	 */
	public float getHealth() {
		return health;
	}

	/**
	 * sets the amount of health the entity has
	 * @param health
	 */
	public void setHealth(float health) {
		this.health = health;
	}
	
	/**
	 * adds the amount provided to the entitys health (use negative to subtract)
	 * @param amount to add
	 */
	public void addToHealth(float health){
		this.health += health;
	}

	/**
	 * gets the entitys coordinates
	 * @return coordinates
	 */
	public FloatVertex2D getCoordinates() {
		return coordinates;
	}

	/**
	 * sets the entitys coordinates
	 * @param coordinates
	 */
	public void setCoordinates(FloatVertex2D coordinates) {
		this.coordinates = coordinates;
	}

	/**
	 * move the entity based on the movement varrable
	 */
	public void move(){
		if(repeatedMovement != null){
			movement.addto(repeatedMovement);
		}
		coordinates.addto(movement);
		if(movement.getX() != 0 && movement.getY() != 0){
			lastMovement = new FloatVertex2D(movement.getX(), movement.getY());
		}
		
		movement.reset();
	}
	
	/**
	 * holds default updating methods for Entity. and should not be overriddin. use updateFirst() or updateLast()
	 */
	public void update(){
		updateFirst();
		
		
		sprite.update(movement);
		
		updateBeforeMove();
		
		move();
		
		
		updateLast();
	}
	
	/**
	 * used to update entity items before the default update method items are called.
	 */
	public void updateFirst(){
		
	}
	
	/**
	 * used to update entity items before the move method is called.
	 */
	public void updateBeforeMove(){
		
	}
	
	/**
	 * used to update entity items after the default update method items are called.
	 */
	public void updateLast(){
		
	}
	
	/**
	 * holds default drawing methods for Entity. and should not be overriddin. use drawFirst() or drawLast()
	 */
	public void draw(Canvas canvas){
		drawFirst(canvas);
		
		if(sprite != null){
			sprite.draw(canvas, coordinates.toIntVertex());
		}
		
		drawLast(canvas);
	}
	
	/**
	 * used to draw entity items before the default draw method items are called.
	 */
	public void drawFirst(Canvas canvas){
		
	}
	
	/**
	 * used to draw entity items after the default draw method items are called.
	 */
	public void drawLast(Canvas canvas){
		
	}
}
